#include "log_print.h"
#include "zlog.h"

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <syslog.h>
#include <time.h>
#include <sys/stat.h>

#define MAX_TOKENS 100   // 最大子字符串数量
#define MAX_TOKEN_LEN 64 // 单个子字符串最大长度

static char tokens[MAX_TOKENS][MAX_TOKEN_LEN] = {0};

// static pthread_mutex_t log_write_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t log_write_mutex;
static int malloc_len = 512;
static char* log_buffer = NULL;
static time_t zlog_conf_last_modified_time = 0;

void log_init()
{
    pthread_mutex_init(&log_write_mutex, NULL);
    /* zlog初始化 */
    if (dzlog_init_ex(ZLOG_CONF, ZLOG_NAME))
    {
        printf("zlog init failed\n");
        exit(-1);
    }

    log_buffer = malloc(malloc_len);
    if (!log_buffer)
    {
        printf("malloc g_log_buffer error\n");
    }else{}

    struct stat file_stat;
    char filename[128] = {'\0'};

    sprintf(filename, "/userdata/dgri/zlog.d/%s", ZLOG_CONF);
    // 获取文件状态，检查文件是否存在
    if (stat(filename, &file_stat) != 0)
    {
        perror("stat failed");
        return ; // 文件不存在或无法获取状态
    }
    zlog_conf_last_modified_time = file_stat.st_mtime;
}

void log_destory()
{
    if(log_buffer)
        free(log_buffer);
    else{}
}

void splitString(const char *str, const char *delimiter, char tokens[MAX_TOKENS][MAX_TOKEN_LEN], int *count)
{
    char *temp = strdup(str); // 创建字符串副本，避免修改原字符串
    char *token;
    *count = 0;

    // 使用 strtok 按分隔符分割字符串
    token = strtok(temp, delimiter);
    while (token != NULL && *count < MAX_TOKENS)
    {
        strncpy(tokens[*count], token, MAX_TOKEN_LEN - 1);
        tokens[*count][MAX_TOKEN_LEN - 1] = '\0'; // 确保字符串以 '\0' 结尾
        (*count)++;
        token = strtok(NULL, delimiter);
    }

    free(temp); // 释放临时字符串副本
}


void log_printf_file_line(int level, const char *file, int line, const char *fmt, ...)
{
    if(!file || !fmt) return;

    pthread_mutex_lock(&log_write_mutex);

    memset(tokens, 0,MAX_TOKEN_LEN*MAX_TOKENS);

    int count = 0;
    //去除文件路径
    splitString(file, "/", tokens, &count);

    const char *file_name = tokens[count - 1];

    int fmt_len = strlen(fmt) + strlen(file_name) +  20; //20字节：int line转字符最长10个字节，其它：%s (%s:%d)

    if (fmt_len > malloc_len)
    {
        //更新log_buffer大小
        malloc_len = malloc_len * 2;
        log_buffer = realloc(log_buffer, malloc_len);
    }
    else
    {
        // do nothing
    }

    const char *format = NULL;
    if (!log_buffer)
    {
        dzlog_printf(ERROR, "log_printf_file_line malloc error");
        format = fmt;
    }else{
        memset(log_buffer, 0, malloc_len);
        sprintf(log_buffer, "%s (%s:%d)", fmt, file_name, line);
        format = log_buffer;
    }

    va_list ap;
    va_start(ap, fmt);
    switch (level) {
        case MSG_VERBOSE:
            vdzlog_debug(format, ap);
            break;
        case MSG_DEBUG:
            vdzlog_debug(format, ap);
            break;
        case MSG_INFO:
            vdzlog_info(format, ap);
            break;
        case MSG_WARNING:
            vdzlog_warn(format, ap);
            break;
        case MSG_ERROR:
            vdzlog_error(format, ap);
            break;
        default:
            vdzlog_debug(format, ap);
            break;
    }
    va_end(ap);
    pthread_mutex_unlock(&log_write_mutex);
}
void log_printf(int level, const char *fmt, ...)
{
    if(!fmt) return;

    va_list ap;
    va_start(ap, fmt);
    switch (level) {
        case MSG_VERBOSE:
            vdzlog_debug(fmt, ap);
            break;
        case MSG_DEBUG:
            vdzlog_debug(fmt, ap);
            break;
        case MSG_INFO:
            vdzlog_info(fmt, ap);
            break;
        case MSG_WARNING:
            vdzlog_warn(fmt, ap);
            break;
        case MSG_ERROR:
            vdzlog_error(fmt, ap);
            break;
        default:
            vdzlog_debug(fmt, ap);
            break;
    }
    va_end(ap);
}

void check_zlog_conf(void)
{
    struct stat file_stat;
    char filename[128] = {'\0'};

    sprintf(filename, "/userdata/dgri/zlog.d/%s", ZLOG_CONF);
    // 获取文件状态，检查文件是否存在
    if (stat(filename, &file_stat) != 0)
    {
        perror("stat failed");
        return ; // 文件不存在或无法获取状态
    }

    // 检查文件是否修改过
    if (file_stat.st_mtime == zlog_conf_last_modified_time)
    {
        // 文件没有修改，不重新读取
        return ;
    }
    else
    {
        // 文件修改过，更新 sys_log_json_file_last_modified_time
        zlog_conf_last_modified_time = file_stat.st_mtime;
        // 重新加载zlog
        dzlog_reload(ZLOG_CONF);
        printf("zlog config File has been modified, reading...\n");
    }
    return ;
}
